/*
 * Copyright(C) 2022. Huawei Technologies Co.,Ltd. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <iostream>
#include <map>
#include <fstream>
#include "unistd.h"
#include <memory>
#include <queue>
#include <thread>
#include "boost/filesystem.hpp"

#include "MxBase/DeviceManager/DeviceManager.h"
#include "MxBase/DvppWrapper/DvppWrapper.h"
#include "MxBase/MemoryHelper/MemoryHelper.h"

#include "MxBase/E2eInfer/ImageProcessor/ImageProcessor.h"
#include "MxBase/E2eInfer/VideoDecoder/VideoDecoder.h"
#include "MxBase/E2eInfer/VideoEncoder/VideoEncoder.h"
#include "MxBase/E2eInfer/DataType.h"

#include "MxBase/MxBase.h"
#include "MxBase/Log/Log.h"

#include "Modules/StreamPuller/StreamPuller.h"
#include "Modules/VideoDecoder/VideoDecoder.h"
#include "ModuleManager/ModuleManager.h"
#include "ModuleIOPortManager/ModuleIOPortManager.h"

bool stop = false;

// void SaveResult(const std::string &savePath, const std::string &inputPort) {
//     FILE *fp = fopen(savePath.c_str(), "wb");
//     if (fp == nullptr)
//     {
//         LogError << "Failed to open file.";
//         return;
//     }
//     uint32_t timeout = 2;//5s
//     uint32_t count = 0;
//     while (true) {
//         if (ModuleIOPortManager::GetInstance().GetSize(inputPort) == 0) {
//             count++;
//             std::this_thread::sleep_for(std::chrono::milliseconds(1000));
//             continue;
//         } else {
//             count = 0;
//         }
//         if (count == timeout) {
//             break;
//         }
//         std::shared_ptr<void> data;
//         ModuleIOPortManager::GetInstance().GetData(inputPort, data);

//         bool bIsIDR = (outDataSize > 1);
//         if (frameImage.frameId)
//         {
//             if (!bIsIDR)
//             {
//                 LogError << "Not bIsIDR!!!";
//                 return APP_ERR_OK;
//             }
//         }
        
//         // write frame to file
//         if (fwrite(outDataPtr.get(), outDataSize, 1, fp) != 1)
//         {
//             LogError << "write frame to file fail";
//             return APP_ERR_COMM_INVALID_PARAM;
//         }

//     }
    
// }

static void Handler(int sig) {
    if (sig == SIGINT) {
        stop = true;
    }
}

int main(int argc, char *argv[])
{
    signal(SIGINT, Handler);

    // global init
    auto ret = MxInit();
    if (ret != APP_ERR_OK) 
    {
        LogError << "MxInit failed, ret=" << ret << ".";
    }

    std::shared_ptr<Module> stream = std::make_shared<StreamPuller>();
    std::shared_ptr<Module> decoder = std::make_shared<Decoder>();
    // std::shared_ptr<Module> encoder = std::make_shared<Encoder>();

    stream->SetInput("file");
    stream->SetOutput("stream");
    decoder->SetInput("stream");
    decoder->SetOutput("decoder");
    // encoder->SetInput("decoder");
    // encoder->SetOutput("encoder");

    ModuleManager::GetInstance().Start({stream, decoder});
    ModuleIOPortManager::GetInstance().SendData("file", std::make_shared<std::string>("test1.264"));
    while (!stop) {
        std::this_thread::sleep_for(std::chrono::milliseconds(50));
    }
    ModuleManager::GetInstance().Stop();
    LogInfo << "ALL DONE";
    return 0;
}